home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gdevpsf1.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  14.8 KB  |  506 lines

  1. /* Copyright (C) 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gdevpsf1.c,v 1.5.2.1 2000/11/09 20:37:29 rayjj Exp $ */
  20. /* Write an embedded Type 1 font */
  21. #include "memory_.h"
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gsccode.h"
  25. #include "gsmatrix.h"
  26. #include "gxfixed.h"
  27. #include "gxfont.h"
  28. #include "gxfont1.h"
  29. #include "gxmatrix.h"        /* for gxtype1.h */
  30. #include "gxtype1.h"
  31. #include "strimpl.h"        /* required by Watcom compiler (why?) */
  32. #include "stream.h"
  33. #include "sfilter.h"
  34. #include "spsdf.h"
  35. #include "sstring.h"
  36. #include "spprint.h"
  37. #include "gdevpsf.h"
  38.  
  39. /* ------ Utilities shared with CFF writer ------ */
  40.  
  41. /* Gather glyph information for a Type 1 or Type 2 font. */
  42. int
  43. psf_type1_glyph_data(gs_font_base *pbfont, gs_glyph glyph,
  44.              gs_const_string *pstr, gs_font_type1 **ppfont)
  45. {
  46.     gs_font_type1 *const pfont = (gs_font_type1 *)pbfont;
  47.  
  48.     *ppfont = pfont;
  49.     return pfont->data.procs.glyph_data(pfont, glyph, pstr);
  50. }
  51. int
  52. psf_get_type1_glyphs(psf_outline_glyphs_t *pglyphs, gs_font_type1 *pfont,
  53.              gs_glyph *subset_glyphs, uint subset_size)
  54. {
  55.     return psf_get_outline_glyphs(pglyphs, (gs_font_base *)pfont,
  56.                   subset_glyphs, subset_size,
  57.                   psf_type1_glyph_data);
  58. }
  59.  
  60. /* ------ Main program ------ */
  61.  
  62. /* Write a (named) array of floats. */
  63. private int
  64. write_float_array(gs_param_list *plist, const char *key, const float *values,
  65.           int count)
  66. {
  67.     if (count != 0) {
  68.     gs_param_float_array fa;
  69.  
  70.     fa.size = count;
  71.     fa.data = values;
  72.     return param_write_float_array(plist, key, &fa);
  73.     }
  74.     return 0;
  75. }
  76.  
  77. /* Write a UniqueID and/or XUID. */
  78. private void
  79. write_uid(stream *s, const gs_uid *puid)
  80. {
  81.     if (uid_is_UniqueID(puid))
  82.     pprintld1(s, "/UniqueID %ld def\n", puid->id);
  83.     else if (uid_is_XUID(puid)) {
  84.     uint i, n = uid_XUID_size(puid);
  85.  
  86.     pputs(s, "/XUID [");
  87.     for (i = 0; i < n; ++i)
  88.         pprintld1(s, "%ld ", uid_XUID_values(puid)[i]);
  89.     pputs(s, "] readonly def\n");
  90.     }
  91. }
  92.  
  93. /* Write the font name. */
  94. private void
  95. write_font_name(stream *s, const gs_font_type1 *pfont,
  96.         const gs_const_string *alt_font_name)
  97. {
  98.     if (alt_font_name)
  99.     pwrite(s, alt_font_name->data, alt_font_name->size);
  100.     else
  101.     pwrite(s, pfont->font_name.chars, pfont->font_name.size);
  102. }
  103. /*
  104.  * Write the Encoding array.  This is a separate procedure only for
  105.  * readability.
  106.  */
  107. private int
  108. write_Encoding(stream *s, gs_font_type1 *pfont, int options,
  109.           gs_glyph *subset_glyphs, uint subset_size, gs_glyph notdef)
  110. {
  111.     pputs(s, "/Encoding ");
  112.     switch (pfont->encoding_index) {
  113.     case ENCODING_INDEX_STANDARD:
  114.         pputs(s, "StandardEncoding");
  115.         break;
  116.     case ENCODING_INDEX_ISOLATIN1:
  117.         /* ATM only recognizes StandardEncoding. */
  118.         if (options & WRITE_TYPE1_POSTSCRIPT) {
  119.         pputs(s, "ISOLatin1Encoding");
  120.         break;
  121.         }
  122.     default:{
  123.         gs_char i;
  124.  
  125.         pputs(s, "256 array\n");
  126.         pputs(s, "0 1 255 {1 index exch /.notdef put} for\n");
  127.         for (i = 0; i < 256; ++i) {
  128.             gs_glyph glyph =
  129.             (*pfont->procs.encode_char)
  130.             ((gs_font *)pfont, (gs_char)i, GLYPH_SPACE_NAME);
  131.             const char *namestr;
  132.             uint namelen;
  133.  
  134.             if (subset_glyphs && subset_size) {
  135.             /*
  136.              * Only write Encoding entries for glyphs in the
  137.              * subset.  Use binary search to check each glyph,
  138.              * since subset_glyphs are sorted.
  139.              */
  140.             if (!psf_sorted_glyphs_include(subset_glyphs,
  141.                             subset_size, glyph))
  142.                 continue;
  143.             }
  144.             if (glyph != gs_no_glyph && glyph != notdef &&
  145.             (namestr = (*pfont->procs.callbacks.glyph_name)
  146.              (glyph, &namelen)) != 0
  147.             ) {
  148.             pprintd1(s, "dup %d /", (int)i);
  149.             pwrite(s, namestr, namelen);
  150.             pputs(s, " put\n");
  151.             }
  152.         }
  153.         pputs(s, "readonly");
  154.         }
  155.     }
  156.     pputs(s, " def\n");
  157.     return 0;
  158. }
  159.  
  160. /*
  161.  * Write the Private dictionary.  This is a separate procedure only for
  162.  * readability.  write_CharString is a parameter so that we can encrypt
  163.  * Subrs and CharStrings when the font's lenIV == -1 but we are writing
  164.  * the font with lenIV = 0.
  165.  */
  166. private int
  167. write_Private(stream *s, gs_font_type1 *pfont,
  168.           gs_glyph *subset_glyphs, uint subset_size,
  169.           gs_glyph notdef, int lenIV,
  170.           int (*write_CharString)(P3(stream *, const void *, uint)),
  171.           const param_printer_params_t *ppp)
  172. {
  173.     const gs_type1_data *const pdata = &pfont->data;
  174.     printer_param_list_t rlist;
  175.     gs_param_list *const plist = (gs_param_list *)&rlist;
  176.     int code = s_init_param_printer(&rlist, ppp, s);
  177.  
  178.     if (code < 0)
  179.     return 0;
  180.     pputs(s, "dup /Private 17 dict dup begin\n");
  181.     pputs(s, "/-|{string currentfile exch readstring pop}executeonly def\n");
  182.     pputs(s, "/|-{noaccess def}executeonly def\n");
  183.     pputs(s, "/|{noaccess put}executeonly def\n");
  184.     {
  185.     private const gs_param_item_t private_items[] = {
  186.         {"BlueFuzz", gs_param_type_int,
  187.          offset_of(gs_type1_data, BlueFuzz)},
  188.         {"BlueScale", gs_param_type_float,
  189.          offset_of(gs_type1_data, BlueScale)},
  190.         {"BlueShift", gs_param_type_float,
  191.          offset_of(gs_type1_data, BlueShift)},
  192.         {"ExpansionFactor", gs_param_type_float,
  193.          offset_of(gs_type1_data, ExpansionFactor)},
  194.         {"ForceBold", gs_param_type_bool,
  195.          offset_of(gs_type1_data, ForceBold)},
  196.         {"LanguageGroup", gs_param_type_int,
  197.          offset_of(gs_type1_data, LanguageGroup)},
  198.         {"RndStemUp", gs_param_type_bool,
  199.          offset_of(gs_type1_data, RndStemUp)},
  200.         gs_param_item_end
  201.     };
  202.     gs_type1_data defaults;
  203.  
  204.     defaults.BlueFuzz = 1;
  205.     defaults.BlueScale = 0.039625;
  206.     defaults.BlueShift = 7.0;
  207.     defaults.ExpansionFactor = 0.06;
  208.     defaults.ForceBold = false;
  209.     defaults.LanguageGroup = 0;
  210.     defaults.RndStemUp = true;
  211.     code = gs_param_write_items(plist, pdata, &defaults, private_items);
  212.     if (code < 0)
  213.         return code;
  214.     if (lenIV != 4) {
  215.         code = param_write_int(plist, "lenIV", &lenIV);
  216.         if (code < 0)
  217.         return code;
  218.     }
  219.     write_float_array(plist, "BlueValues", pdata->BlueValues.values,
  220.               pdata->BlueValues.count);
  221.     write_float_array(plist, "OtherBlues", pdata->OtherBlues.values,
  222.               pdata->OtherBlues.count);
  223.     write_float_array(plist, "FamilyBlues", pdata->FamilyBlues.values,
  224.               pdata->FamilyBlues.count);
  225.     write_float_array(plist, "FamilyOtherBlues", pdata->FamilyOtherBlues.values,
  226.               pdata->FamilyOtherBlues.count);
  227.     write_float_array(plist, "StdHW", pdata->StdHW.values,
  228.               pdata->StdHW.count);
  229.     write_float_array(plist, "StemSnapH", pdata->StemSnapH.values,
  230.               pdata->StemSnapH.count);
  231.     write_float_array(plist, "StemSnapV", pdata->StemSnapV.values,
  232.               pdata->StemSnapV.count);
  233.     }
  234.     write_uid(s, &pfont->UID);
  235.     pputs(s, "/MinFeature{16 16} def\n");
  236.     pputs(s, "/password 5839 def\n");
  237.  
  238.     /*
  239.      * Write the Subrs.  We always write them all, even for subsets.
  240.      * (We will fix this someday.)
  241.      */
  242.  
  243.     {
  244.     int n, i;
  245.     gs_const_string str;
  246.  
  247.     for (n = 0;
  248.          (*pdata->procs.subr_data)(pfont, n, false, &str) !=
  249.          gs_error_rangecheck;
  250.         )
  251.         ++n;
  252.     pprintd1(s, "/Subrs %d array\n", n);
  253.     for (i = 0; i < n; ++i)
  254.         if ((*pdata->procs.subr_data)(pfont, i, false, &str) >= 0) {
  255.         char buf[50];
  256.  
  257.         sprintf(buf, "dup %d %u -| ", i, str.size);
  258.         pputs(s, buf);
  259.         write_CharString(s, str.data, str.size);
  260.         pputs(s, " |\n");
  261.         }
  262.     pputs(s, "|-\n");
  263.     }
  264.  
  265.     /* We don't write OtherSubrs -- there had better not be any! */
  266.  
  267.     /* Write the CharStrings. */
  268.  
  269.     {
  270.     int num_chars = 0;
  271.     gs_glyph glyph;
  272.     psf_glyph_enum_t genum;
  273.     gs_const_string gdata;
  274.     int code;
  275.  
  276.     psf_enumerate_glyphs_begin(&genum, (gs_font *)pfont, subset_glyphs,
  277.                     (subset_glyphs ? subset_size : 0),
  278.                     GLYPH_SPACE_NAME);
  279.     for (glyph = gs_no_glyph;
  280.          (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
  281.          )
  282.         if (code == 0 && (*pdata->procs.glyph_data)(pfont, glyph, &gdata) >= 0)
  283.         ++num_chars;
  284.     pprintd1(s, "2 index /CharStrings %d dict dup begin\n", num_chars);
  285.     psf_enumerate_glyphs_reset(&genum);
  286.     for (glyph = gs_no_glyph;
  287.          (code = psf_enumerate_glyphs_next(&genum, &glyph)) != 1;
  288.         )
  289.         if (code == 0 && (*pdata->procs.glyph_data)(pfont, glyph, &gdata) >= 0) {
  290.         uint gssize;
  291.         const char *gstr =
  292.             (*pfont->procs.callbacks.glyph_name)(glyph, &gssize);
  293.  
  294.         pputs(s, "/");
  295.         pwrite(s, gstr, gssize);
  296.         pprintd1(s, " %d -| ", gdata.size);
  297.         write_CharString(s, gdata.data, gdata.size);
  298.         pputs(s, " |-\n");
  299.         }
  300.     }
  301.  
  302.     /* Wrap up. */
  303.  
  304.     pputs(s, "end\nend\nreadonly put\nnoaccess put\n");
  305.     s_release_param_printer(&rlist);
  306.     return 0;
  307. }
  308.  
  309. /* Encrypt and write a CharString. */
  310. private int
  311. pwrite_encrypted(stream *s, const void *ptr, uint count)
  312. {
  313.     const byte *const data = ptr;
  314.     crypt_state state = crypt_charstring_seed;
  315.     byte buf[50];        /* arbitrary */
  316.     uint left, n;
  317.     int code = 0;
  318.  
  319.     for (left = count; left > 0; left -= n) {
  320.     n = min(left, sizeof(buf));
  321.     gs_type1_encrypt(buf, data + count - left, n, &state);
  322.     code = pwrite(s, buf, n);
  323.     }
  324.     return code;
  325. }
  326.  
  327. /* Write one FontInfo entry. */
  328. private void
  329. write_font_info(stream *s, const char *key, const gs_const_string *pvalue,
  330.         int do_write)
  331. {
  332.     if (do_write) {
  333.     pprints1(s, "\n/%s ", key);
  334.     s_write_ps_string(s, pvalue->data, pvalue->size, PRINT_HEX_NOT_OK);
  335.     pputs(s, " def");
  336.     }
  337. }
  338.  
  339. /* Write the definition of a Type 1 font. */
  340. int
  341. psf_write_type1_font(stream *s, gs_font_type1 *pfont, int options,
  342.               gs_glyph *orig_subset_glyphs, uint orig_subset_size,
  343.               const gs_const_string *alt_font_name, int lengths[3])
  344. {
  345.     stream *es = s;
  346.     long start = stell(s);
  347.     param_printer_params_t ppp;
  348.     printer_param_list_t rlist;
  349.     gs_param_list *const plist = (gs_param_list *)&rlist;
  350.     stream AXE_stream;
  351.     stream_AXE_state AXE_state;
  352.     byte AXE_buf[200];        /* arbitrary */
  353.     stream exE_stream;
  354.     stream_exE_state exE_state;
  355.     byte exE_buf[200];        /* arbitrary */
  356.     psf_outline_glyphs_t glyphs;
  357.     int lenIV = pfont->data.lenIV;
  358.     int (*write_CharString)(P3(stream *, const void *, uint)) = pwrite;
  359.     int code = psf_get_type1_glyphs(&glyphs, pfont, orig_subset_glyphs,
  360.                      orig_subset_size);
  361.  
  362.     if (code < 0)
  363.     return code;
  364.  
  365.     /* Initialize the parameter printer. */
  366.  
  367.     ppp = param_printer_params_default;
  368.     ppp.item_suffix = " def\n";
  369.     ppp.print_ok =
  370.     (options & WRITE_TYPE1_ASCIIHEX ? 0 : PRINT_BINARY_OK) |
  371.     PRINT_HEX_NOT_OK;
  372.     code = s_init_param_printer(&rlist, &ppp, s);
  373.     if (code < 0)
  374.     return code;
  375.  
  376.     /* Write the font header. */
  377.  
  378.     pputs(s, "%!FontType1-1.0: ");
  379.     write_font_name(s, pfont, alt_font_name);
  380.     pputs(s, "\n11 dict begin\n");
  381.  
  382.     /* Write FontInfo. */
  383.  
  384.     pputs(s, "/FontInfo 5 dict dup begin");
  385.     {
  386.     gs_font_info_t info;
  387.     int code = pfont->procs.font_info((gs_font *)pfont, NULL,
  388.             (FONT_INFO_COPYRIGHT | FONT_INFO_NOTICE |
  389.              FONT_INFO_FAMILY_NAME | FONT_INFO_FULL_NAME),
  390.                       &info);
  391.  
  392.     if (code >= 0) {
  393.         write_font_info(s, "Copyright", &info.Copyright,
  394.                 info.members & FONT_INFO_COPYRIGHT);
  395.         write_font_info(s, "Notice", &info.Notice,
  396.                 info.members & FONT_INFO_NOTICE);
  397.         write_font_info(s, "FamilyName", &info.FamilyName,
  398.                 info.members & FONT_INFO_FAMILY_NAME);
  399.         write_font_info(s, "FullName", &info.FullName,
  400.                 info.members & FONT_INFO_FULL_NAME);
  401.     }
  402.     }
  403.     pputs(s, "\nend readonly def\n");
  404.  
  405.     /* Write the main font dictionary. */
  406.  
  407.     pputs(s, "/FontName /");
  408.     write_font_name(s, pfont, alt_font_name);
  409.     pputs(s, " def\n");
  410.     code = write_Encoding(s, pfont, options, glyphs.subset_glyphs,
  411.               glyphs.subset_size, glyphs.notdef);
  412.     if (code < 0)
  413.     return code;
  414.     pprintg6(s, "/FontMatrix [%g %g %g %g %g %g] readonly def\n",
  415.          pfont->FontMatrix.xx, pfont->FontMatrix.xy,
  416.          pfont->FontMatrix.yx, pfont->FontMatrix.yy,
  417.          pfont->FontMatrix.tx, pfont->FontMatrix.ty);
  418.     write_uid(s, &pfont->UID);
  419.     pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n",
  420.          pfont->FontBBox.p.x, pfont->FontBBox.p.y,
  421.          pfont->FontBBox.q.x, pfont->FontBBox.q.y);
  422.     {
  423.     private const gs_param_item_t font_items[] = {
  424.         {"FontType", gs_param_type_int,
  425.          offset_of(gs_font_type1, FontType)},
  426.         {"PaintType", gs_param_type_int,
  427.          offset_of(gs_font_type1, PaintType)},
  428.         {"StrokeWidth", gs_param_type_float,
  429.          offset_of(gs_font_type1, StrokeWidth)},
  430.         gs_param_item_end
  431.     };
  432.  
  433.     code = gs_param_write_items(plist, pfont, NULL, font_items);
  434.     if (code < 0)
  435.         return code;
  436.     }
  437.     {
  438.     const gs_type1_data *const pdata = &pfont->data;
  439.  
  440.     write_float_array(plist, "WeightVector", pdata->WeightVector.values,
  441.               pdata->WeightVector.count);
  442.     }
  443.     pputs(s, "currentdict end\n");
  444.  
  445.     /* Write the Private dictionary. */
  446.  
  447.     if (lenIV < 0 && (options & WRITE_TYPE1_WITH_LENIV)) {
  448.     /* We'll have to encrypt the CharStrings. */
  449.     lenIV = 0;
  450.     write_CharString = pwrite_encrypted;
  451.     }
  452.     if (options & WRITE_TYPE1_EEXEC) {
  453.     pputs(s, "currentfile eexec\n");
  454.     lengths[0] = stell(s) - start;
  455.     start = stell(s);
  456.     if (options & WRITE_TYPE1_ASCIIHEX) {
  457.         s_init(&AXE_stream, NULL);
  458.         s_init_state((stream_state *)&AXE_state, &s_AXE_template, NULL);
  459.         AXE_state.EndOfData = false;
  460.         s_init_filter(&AXE_stream, (stream_state *)&AXE_state,
  461.               AXE_buf, sizeof(AXE_buf), es);
  462.         es = &AXE_stream;
  463.     }
  464.     s_init(&exE_stream, NULL);
  465.     s_init_state((stream_state *)&exE_state, &s_exE_template, NULL);
  466.     exE_state.cstate = 55665;
  467.     s_init_filter(&exE_stream, (stream_state *)&exE_state,
  468.               exE_buf, sizeof(exE_buf), es);
  469.     es = &exE_stream;
  470.     /*
  471.      * Note: eexec encryption always writes/skips 4 initial bytes, not
  472.      * the number of initial bytes given by pdata->lenIV.
  473.      */
  474.     pputs(es, "****");
  475.     }
  476.     code = write_Private(es, pfont, glyphs.subset_glyphs, glyphs.subset_size,
  477.              glyphs.notdef, lenIV, write_CharString, &ppp);
  478.     if (code < 0)
  479.     return code;
  480.     pputs(es, "dup/FontName get exch definefont pop\n");
  481.     if (options & WRITE_TYPE1_EEXEC) {
  482.     if (options & (WRITE_TYPE1_EEXEC_PAD | WRITE_TYPE1_EEXEC_MARK))
  483.         pputs(es, "mark ");
  484.     pputs(es, "currentfile closefile\n");
  485.     s_close_filters(&es, s);
  486.     lengths[1] = stell(s) - start;
  487.     start = stell(s);
  488.     if (options & WRITE_TYPE1_EEXEC_PAD) {
  489.         int i;
  490.  
  491.         for (i = 0; i < 8; ++i)
  492.         pputs(s, "\n0000000000000000000000000000000000000000000000000000000000000000");
  493.         pputs(s, "\ncleartomark\n");
  494.     }
  495.     lengths[2] = stell(s) - start;
  496.     } else {
  497.     lengths[0] = stell(s) - start;
  498.     lengths[1] = lengths[2] = 0;
  499.     }
  500.  
  501.     /* Wrap up. */
  502.  
  503.     s_release_param_printer(&rlist);
  504.     return 0;
  505. }
  506.